/*
 * 密度(度目)
 * 舞者无罪
 * 2014.12.02
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include "resource.h"
#include "func.h"
#include "lang.h"
#include "density.h"
#include "com.h"
#include "mhlabel.h"
#include "mhbtn.h"
#include "keypane.h"
#include "info.h"

#define DENSITY_CAPTION_LEFT       110
#define DENSITY_CAPTION_WIDTH      80
#define DENSITY_NUM_LEFT           CX_EDGE_LEFT
#define DENSITY_CAPTION_TOP        (CY_TITLE4_HEIGHT + CX_EDGE_LEFT)
#define DENSITY_NUM_WIDTH          30
#define DENSITY_NUM_HEIGHT         20
#define DENSITY_VALUE_INTER        11
/*
 *
 */
static void CreateDensityInterface(HWND hWnd)
{
    int i = 0, j = 0;
    HWND hTmp = -1;
    CreateWindow (MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_FALSE,
        CX_XTCS_WND_BMP - CX_ASK_BMP * 2,
        10,
        CX_ASK_BMP,
        CY_ASK_BMP,
        hWnd, (int)&g_bmp[BMP_FALSE]);
    CreateWindow (MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_TRUE,
        CX_XTCS_WND_BMP - CX_ASK_BMP * 3 - 8,
        10,
        CX_ASK_BMP,
        CY_ASK_BMP,
        hWnd, (int)&g_bmp[BMP_TRUE]);
    CreateWindow (MH_STATIC_NAME,
        "",
        WS_CHILD | WS_VISIBLE,
        ID_ESC,
        CX_XTCS_WND_BMP - CX_ASK_BMP * 4 - 8 * 2,
        10,
        CX_ASK_BMP,
        CY_ASK_BMP,
        hWnd, (int)&g_bmp[BMP_ASK]);

    CreateWindow(MH_LABEL_NAME,
        MW_RGHT_USED_CAPTION,
        WS_CHILD | WS_VISIBLE,
        IDC_STATIC,
        DENSITY_CAPTION_LEFT,
        DENSITY_CAPTION_TOP,
        DENSITY_CAPTION_WIDTH,
        DENSITY_NUM_HEIGHT,
        hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
    CreateWindow(MH_LABEL_NAME,
        MW_LEFT_USED_CAPTION,
        WS_CHILD | WS_VISIBLE,
        IDC_STATIC,
        DENSITY_CAPTION_LEFT + DENSITY_CAPTION_WIDTH * 2,
        DENSITY_CAPTION_TOP,
        DENSITY_CAPTION_WIDTH,
        DENSITY_NUM_HEIGHT,
        hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
    CreateWindow(MH_LABEL_NAME,
        MW_RGHT_USED_CAPTION,
        WS_CHILD | WS_VISIBLE,
        IDC_STATIC,
        DENSITY_CAPTION_LEFT + CX_SCREEN / 2,
        DENSITY_CAPTION_TOP,
        DENSITY_CAPTION_WIDTH,
        DENSITY_NUM_HEIGHT,
        hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
    CreateWindow(MH_LABEL_NAME,
        MW_LEFT_USED_CAPTION,
        WS_CHILD | WS_VISIBLE,
        IDC_STATIC,
        DENSITY_CAPTION_LEFT + CX_SCREEN / 2 + DENSITY_CAPTION_WIDTH * 2,
        DENSITY_CAPTION_TOP,
        DENSITY_CAPTION_WIDTH,
        DENSITY_NUM_HEIGHT,
        hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
    for(i = 0; i < 2; ++i)
    {
        const char *str[8] = {
            MW_BACK1_CAPTION,
            MW_BACK2_CAPTION,
            MW_FRNT1_CAPTION,
            MW_FRNT2_CAPTION,
            MW_BACK1_CAPTION,
            MW_BACK2_CAPTION,
            MW_FRNT1_CAPTION,
            MW_FRNT2_CAPTION,
        };
        for(j = 0; j < DUMU_NUM; ++j)
        {
            CreateWindow(MH_LABEL_NAME,
                str[j],
                WS_CHILD | BS_FLAT | WS_VISIBLE,
                IDC_STATIC,
                DENSITY_NUM_LEFT + (j + 1) * (DENSITY_NUM_WIDTH + DENSITY_VALUE_INTER) + i * CX_SCREEN / 2,
                DENSITY_CAPTION_TOP + DENSITY_NUM_HEIGHT,
                DENSITY_NUM_WIDTH,
                DENSITY_NUM_HEIGHT,
                hWnd, MH_LABEL_BKGND_BLACK | MH_LABEL_TEXT_GREEN);
        }
    }
    int fb[8] = {1, 1, 0, 0, 1, 1, 0, 0};
    int dumu_no[8] = {0, 2, 0, 2, 1, 3, 1, 3};
    uint used_sect = GetUsedDensitySect(g_knit_data);
    for(i = 0; i < MAX_DUMU_SECT; ++i)
    {
        char str[32] = {0};
        sprintf(str, "#%02d", i + 1);
        hTmp = CreateWindow(MH_BTN_NAME,
            str,
            WS_CHILD | BS_FLAT | WS_VISIBLE,
            ID_1NUM + i,
            DENSITY_NUM_LEFT + (i < MAX_DUMU_SECT / 2 ? 0 : CX_SCREEN / 2),
            DENSITY_CAPTION_TOP + DENSITY_NUM_HEIGHT * (2 + (i & 0x0F)),
            DENSITY_NUM_WIDTH,
            DENSITY_NUM_HEIGHT,
            hWnd,
            MH_BTN_BKGND_BLACK | ((used_sect & (1 << i)) ? MH_BTN_TEXT_RED : MH_BTN_TEXT_GREEN));
        EnableWindow(hTmp, FALSE);
        for(j = 0; j < DUMU_NUM; ++j)
        {
            sprintf(str, "%u", GetRunDumu(g_knit_data, fb[j], i, dumu_no[j]));
            CreateWindow(MH_EDIT_NAME,
                str,
                WS_CHILD | WS_VISIBLE,
                IDC_EDIT1 + i * DUMU_NUM + j,
                DENSITY_NUM_LEFT + (j + 1) * (DENSITY_NUM_WIDTH + DENSITY_VALUE_INTER) + (i < MAX_DUMU_SECT / 2 ? 0 : CX_SCREEN / 2),
                DENSITY_CAPTION_TOP + DENSITY_NUM_HEIGHT * (2 + (i & 0x0F)),
                DENSITY_NUM_WIDTH,
                DENSITY_NUM_HEIGHT,
                hWnd, 0);
        }
    }
}
/*
 *
 */
static void OnSetKnitValue(HWND hWnd, int nID)
{
    WND_EXTRA_DATA data;
    data.value = GetWindowAdditionalData(hWnd);
    data.density.change = TRUE;
    const char *sc = GetWindowCaption(GetDlgItem(hWnd, nID));
    ushort n = atoi(sc);
    int sect = (nID - IDC_EDIT1) >> 3;
    switch((nID - IDC_EDIT1) & 0x07)
    {
    case 0:
        SetRunDumu(g_knit_data, 1, sect, 0, n);
        break;
    case 1:
        SetRunDumu(g_knit_data, 1, sect, 2, n);
        break;
    case 2:
        SetRunDumu(g_knit_data, 0, sect, 0, n);
        break;
    case 3:
        SetRunDumu(g_knit_data, 0, sect, 2, n);
        break;
    case 4:
        SetRunDumu(g_knit_data, 1, sect, 1, n);
        break;
    case 5:
        SetRunDumu(g_knit_data, 1, sect, 3, n);
        break;
    case 6:
        SetRunDumu(g_knit_data, 0, sect, 1, n);
        break;
    case 7:
        SetRunDumu(g_knit_data, 0, sect, 3, n);
        break;
    }
    SetWindowAdditionalData(hWnd, data.value);
}
/*
 *
 */
static void OnBtnCmd(HWND hWnd, int nID)
{
    if(nID >= ID_1NUM && nID <= ID_32NUM)
    {
        //CreateHelpWindow(hWnd);
    }
    else if(nID >= IDC_EDIT1 && nID < IDC_EDIT1 + MAX_DUMU_SECT * DUMU_NUM)
    {
        HWND hTmp = GetDlgItem(hWnd, nID);
        RECT rect;
        GetClientRect(hTmp, &rect);
        ClientToScreen(hTmp, &rect.left, &rect.top);
        ClientToScreen(hTmp, &rect.right, &rect.bottom);
        CreateKeyboardWindow(hWnd, rect, -400, 400, atoi(GetWindowCaption(hTmp)));
    }
    else if(nID == ID_TRUE)
    {
        WND_EXTRA_DATA data;
        data.value = GetWindowAdditionalData(hWnd);
        if(data.density.change)
        {
            char sc[MH_FILE_NAME_MAX_LEN + sizeof(KNIT_FILE_DIR) + sizeof(".stp")] = { 0 };
            strcat(sc, KNIT_FILE_DIR);
            strcat(sc, GetKnitFileName(g_knit_data));
            strcat(sc, ".stp");
            int ret = WriteDumuFile(sc, g_knit_data);
            if(ret)
            {
                printf("fail to write dumu file: %d\n", ret);
                AddSysLog(g_knit_data, LOG_TYPE_FILE, ret);
                AfxInfoBox(hWnd, NULL, GetString(481));
            }
            else
            {
                MH_FILE_SYNC();
                data.density.change = FALSE;
                SetWindowAdditionalData(hWnd, data.value);
            }
            SendDumuParam(g_knit_data);
        }
        PostMessage (hWnd, MSG_CLOSE, 0, 0);
    }
    else if(ID_FALSE)
    {
        WND_EXTRA_DATA data;
        data.value = GetWindowAdditionalData(hWnd);
        if(data.density.change)
        {
            char sc[MH_FILE_NAME_MAX_LEN + sizeof(KNIT_FILE_DIR) + sizeof(".stp")] = { 0 };
            strcat(sc, KNIT_FILE_DIR);
            strcat(sc, GetKnitFileName(g_knit_data));
            strcat(sc, ".stp");
            int ret = ReadDumuData(sc, g_knit_data);
            if(ret)
            {
                printf("fail to read dumu file: %d\n", ret);
                AddSysLog(g_knit_data, LOG_TYPE_FILE, ret);
                AfxInfoBox(hWnd, NULL, GetString(481));
            }
        }
        PostMessage(hWnd, MSG_CLOSE, 0, 0);
    }
}
/*
 *
 */
static void OnKeyDown(HWND hWnd, uint key)
{
    if(key == SCANCODE_ESCAPE)
    {
        OnBtnCmd(hWnd, ID_TRUE);
    }
    else if(key == SCANCODE_ENTER)
    {
        ushort nID = GetDlgCtrlID(GetFocusChild(hWnd));
        if(nID >= IDC_EDIT1 && nID < IDC_EDIT1 + IDC_EDIT1 + MAX_DUMU_SECT * DUMU_NUM)
        {
            HWND hTmp = GetDlgItem(hWnd, nID);
            RECT rect;
            GetClientRect(hTmp, &rect);
            ClientToScreen(hTmp, &rect.left, &rect.top);
            ClientToScreen(hTmp, &rect.right, &rect.bottom);
            int value = atoi(GetWindowCaption(hTmp));
            CreateKeyboardWindow(hWnd, rect, 0, 800, value);
        }
    }
    else if(key == SCANCODE_CURSORBLOCKRIGHT)
    {
        int nID = GetDlgCtrlID(GetFocusChild(hWnd));
        if(((nID - IDC_EDIT1) & 7) < 7)
        {
            ++nID;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
        else if(nID - IDC_EDIT1 < MAX_DUMU_SECT / 2 * DUMU_NUM)
        {
            nID += MAX_DUMU_SECT / 2 * DUMU_NUM - (DUMU_NUM - 1);
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
    }
    else if(key == SCANCODE_CURSORBLOCKLEFT)
    {
        int nID = GetDlgCtrlID(GetFocusChild(hWnd));
        if(((nID - IDC_EDIT1) & 7) > 0)
        {
            --nID;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
        else if(nID - IDC_EDIT1 >= MAX_DUMU_SECT / 2 * DUMU_NUM)
        {
            nID -= MAX_DUMU_SECT / 2 * DUMU_NUM - (DUMU_NUM - 1);
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
    }
    else if(key == SCANCODE_CURSORBLOCKUP)
    {
        int nID = GetDlgCtrlID(GetFocusChild(hWnd));
        if(nID - IDC_EDIT1 >= DUMU_NUM)
        {
            nID -= DUMU_NUM;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
    }
    else if(key == SCANCODE_CURSORBLOCKDOWN)
    {
        int nID = GetDlgCtrlID(GetFocusChild(hWnd));
        if(nID - IDC_EDIT1 < (MAX_DUMU_SECT - 1) * DUMU_NUM)
        {
            nID += DUMU_NUM;
            SetFocusChild(GetDlgItem(hWnd, nID));
        }
    }
    else if(key == SCANCODE_C)
    {
        ushort nID = GetDlgCtrlID(GetFocusChild(hWnd));
        if(nID >= IDC_EDIT1 && nID < IDC_EDIT1 + MAX_DUMU_SECT * DUMU_NUM)
        {
            int sect = (nID - IDC_EDIT1) >> 3;
            HWND hTmp = GetDlgItem(hWnd, nID);
            ushort n = 0;
            const char *sc = GetWindowCaption(hTmp);
            if(sc)
            {
                n = atoi(sc);
            }
            CopyKnitDumu(g_knit_data, 0, sect, n);
            CopyKnitDumu(g_knit_data, 1, sect, n);
            int i = 0;
            for(i = 0; i < 8; ++i)
            {
                hTmp = GetDlgItem(hWnd, IDC_EDIT1 + sect * 8 + i);
                SetWindowCaption(hTmp, sc);
                InvalidateRect(hTmp, NULL, TRUE);
            }
            WND_EXTRA_DATA data;
            data.value = GetWindowAdditionalData(hWnd);
            data.density.change = TRUE;
            SetWindowAdditionalData(hWnd, data.value);
        }
    }
}
/*
 *
 */
static int DensityWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
    case MSG_CREATE:
        {
            CreateDensityInterface(hWnd);
        }
        break;
    case MSG_PAINT:
        {
            HDC hdc = GetClientDC(hWnd);
            RECT rect;
            GetClientRect(hWnd, &rect);
            rect.left += 200;
            rect.top += MASTER_TITLE_TOP;
            rect.right -= 200;
            rect.bottom = rect.top + MASTER_TITLE_HEIGHT - 1;
            SetBkMode(hdc, BM_TRANSPARENT);
            SetTextColor(hdc, COLOR_HQ_GREEN(hdc));
            DrawText(hdc, GetWindowCaption (hWnd), -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
            ReleaseDC(hdc);
        }
        break;
    case MSG_CLOSE:
        {
            HWND hHosting = GetHosting(hWnd);
            if(hHosting != HWND_INVALID)
            {
                EnableWindow(hHosting, TRUE);
            }
            DestroyMainWindow(hWnd);
            MainWindowCleanup(hWnd);
        }
        return 0;
    case MSG_DESTROY:
        {
            ShowWindow(hWnd, SW_HIDE);
            DestroyAllControls(hWnd);
        }
        break;
    case MSG_KEYDOWN:
        {
            OnKeyDown(hWnd, LOWORD(wParam));
        }
        return 0;
    case MSG_ERASEBKGND:
        {
            DrawBitmapBkGnd(hWnd, (RECT*)lParam, &g_bmp[BMP_XTCS]);
        }
        return 0;
    case MSG_COMMAND:
        {
            OnBtnCmd(hWnd, LOWORD(wParam));
        }
        return 0;
    case MSG_SETDATA:
        {
            OnSetKnitValue(hWnd, LOWORD(wParam));
        }
        return 0;
    }
    return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
/*
 *
 */
HWND CreateDensityWindow(HWND hHosting)
{
    int x = (CX_SCREEN - CX_XTCS_WND_BMP) / 2;
    int y = (CY_SCREEN - CY_XTCS_WND_BMP) / 2;
    MAINWINCREATE CreateInfo;
    CreateInfo.dwStyle = WS_VISIBLE;
    CreateInfo.dwExStyle = WS_EX_NONE;
    CreateInfo.spCaption = MW_WORK_DUMU_SET_CAPTION;
    CreateInfo.hMenu = 0;
    CreateInfo.hCursor = GetSystemCursor(0);
    CreateInfo.hIcon = 0;
    CreateInfo.MainWindowProc = DensityWinProc;
    CreateInfo.lx = x;
    CreateInfo.ty = y;
    CreateInfo.rx = x + CX_XTCS_WND_BMP;
    CreateInfo.by = y + CY_XTCS_WND_BMP;
    CreateInfo.iBkColor = COLOR_lightwhite;
    CreateInfo.dwAddData = 0;
    CreateInfo.hHosting = hHosting;
    HWND hWnd = CreateMainWindow(&CreateInfo);
    if(hWnd != HWND_INVALID)
    {
        EnableWindow(hHosting, FALSE);
        SetFocusChild(GetDlgItem(hWnd, IDC_EDIT1));
        ShowWindow(hWnd, SW_SHOWNORMAL);
    }
    return hWnd;
}
